//
// Created by wxd on 2025/7/28.
//

/**
 * FPS视角相机算法实现
 * WASD：控制前后左右相机的移动
 * 鼠标：控制相机的视角，朝向那一侧进行观察
 * 分析具体算法实现
 * 自定义引擎中的相机系统的矩阵构建参数：{ pos, up, right }， 先给出相关的符号约定：
 *   1. 移动速度：v
 *   2. 相机观察方向：f
 *
 * wasd更新：pos
 * 鼠标更新：up，right
 */

#pragma once

#include "BaseCameraControl.h"

enum class CameraMoveType {
    MOTIONLESS, LEFT, RIGHT, BACK, FORWARD
};

class GameFPSCameraControl : public BaseCameraControl {
public:
    GameFPSCameraControl() {}
    explicit GameFPSCameraControl(const float speed) : m_CameraMoveSpeed(speed) {}

    GameFPSCameraControl(const float speed, const float windowWidth, const float windowHeight)
        : m_CameraMoveSpeed(speed) {
        setMouseCenter(windowWidth, windowHeight);
    }

    GameFPSCameraControl(const float speed, const float sensitivity, const float windowWidth, const float windowHeight)
        : m_CameraMoveSpeed(speed), m_MouseSensitivity(sensitivity) {
        setMouseCenter(windowWidth, windowHeight);
    }

    GameFPSCameraControl(const float speed, const float sensitivity,
        const float minPitch, const float maxPitch, const float windowWidth, const float windowHeight)
        : m_CameraMoveSpeed(speed), m_MouseSensitivity(sensitivity), m_MaxPitch(maxPitch), m_MinPitch(minPitch) {
        setMouseCenter(windowWidth, windowHeight);
    }

    void onKeyBoard(int key, int action, int mods) override;
    void onCursor(float xpos, float ypos) override;
    void onScroll(double yoffset) override;
    void update() override;

    void setMouseCenter(const float windowWidth, const float windowHeight); // 初始化FPS控制器鼠标初始化中心坐标
    void setSpeed(const float speed);
    void setSensitivity(const float sensitivity);
    void setMaxPitch(const float maxPitch);
    void setMinPitch(const float minPitch);
    void setPitchRange(const float maxPitch, const float minPitch);

    float getSpeed() const;
    float getSensitivity() const;
    float getMaxPitch() const;
    float getMinPitch() const;
private:
    float m_CameraMoveSpeed  { 0.f };
    float m_MouseSensitivity { 0.f };
    float m_AccPitch         { 0.f };

    // 控制pitch的变化范围
    float m_MaxPitch         { 89.f  };
    float m_MinPitch         { -89.f };

    // 相机当前的移动类型
    CameraMoveType m_CameraMoveType { CameraMoveType::MOTIONLESS };

    bool isBetweenPitchRange(float curPitch) const;
    void onCameraMoveEvent();
    void onCameraGazeEvent(float dPitch, float dYaw);

    bool isLeftMove();
    bool isRightMove();
    bool isBackMove();
    bool isForwardMove();

    void updatePitch(const float angle);
    void updateYaw(const float angle);
};


